//
//  HistoryGenericVariable.m
//  LogAnything
//
//  Created by Daniel Braun on 19/06/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "HistoryGenericVariable.h"


@implementation HistoEntryGen

- (void) dealloc {
	[_values release];
	[super dealloc];
}

- (id) init {
	self = [super init];
	if (self != nil) {
		_values=[[NSMutableDictionary dictionaryWithCapacity:10]retain]; 
	}
	return self;
}


- (void)encodeWithCoder:(NSCoder *)coder
{
	[super encodeWithCoder:coder];
	if ( [coder allowsKeyedCoding] ) {
		[coder encodeObject:_values forKey:@"values"];
	}
}

- (id) initWithCoder:(NSCoder *) coder
{
	self=[super initWithCoder:coder];
	if ([coder allowsKeyedCoding]) {
		_values=[[coder decodeObjectForKey:@"values"]retain];
		return self;
	}
failed:
	[self release];
	return nil;
}


@end


@implementation HistoryGenericVariable

- (id) init {
	self = [super init];
	if (self != nil) {
		knownKeys=[[NSMutableDictionary dictionaryWithCapacity:10]retain];
	}
	return self;
}

- (void) dealloc {
	[knownKeys release];
	[super dealloc];
}

- (void)encodeWithCoder:(NSCoder *)coder
{
	[super encodeWithCoder:coder];
	if ( [coder allowsKeyedCoding] ) {
		[coder encodeObject:knownKeys forKey:@"knownKeys"];
	}
}

- (id) initWithCoder:(NSCoder *) coder
{
	self=[super initWithCoder:coder];
	if ([coder allowsKeyedCoding]) {
		knownKeys=[[coder decodeObjectForKey:@"knownKeys"]retain];
		return self;
	}
failed:
	[self release];
	return nil;
}


- (void) setValue:(id)value forKey:(id)key
{
	[self setValue:value forKey:key atDate:[NSDate date]];
}

- (void) setValue:(id)value forKey:(id)key atDate:(NSDate *)d
{
 	[knownKeys setObject:value forKey:key];
	HistoEntryGen *vref=[[[HistoEntryGen alloc]initWithDate:d]autorelease];
	HistoEntryGen *v=[self member:vref];
	if (!v) {
		v=[[[HistoEntryGen alloc]initWithDate:d]autorelease];
		[self addObject:v];
	}
	NSAssert(v->_values, @"should have a dic");
	[v->_values setObject:value forKey:key];
}

- (void) setAllValues:(NSDictionary *)d atDate:(NSDate *)date
{
	HistoEntryGen *v=[[HistoEntryGen alloc]initWithDate:date];
	[knownKeys addEntriesFromDictionary:d];
	v->_values=[d mutableCopy];
	[self addObject:v];
	[v release];
}	

- (id) valueForKey:(id)key atDate:(NSDate *)date
{
	HistoEntryGen *vref=[[HistoEntryGen alloc]initWithDate:date];
	[vref release];
	HistoEntryGen *v;
	NSEnumerator *en=[self objectEnumeratorForSmallerOrEqualMember:vref];
	for (;en;v=[en prevObject]) {
		if (!v) {
			NSLog(@"valueForKey:atDate:, no object for date %@\n", date);
			return nil;
		}
		id val=[v->_values objectForKey:key];
		if (val) return val;
		v=[self predecessorForObject:v];
	}
	return nil;
}
- (NSDictionary *) allValuesAtDate:(NSDate *)date maxDateDelta:(NSTimeInterval)md
{
	NSMutableDictionary *res=[NSMutableDictionary dictionaryWithCapacity:10];
	int c;
	c=[knownKeys count];
	if (!c) return res;
	NSDate *mindate=nil;
	if (md) mindate=[[[NSDate alloc]initWithTimeInterval:-md sinceDate:date]autorelease];
	HistoEntryGen *vref=[[[HistoEntryGen alloc]initWithDate:date]autorelease];
	NSEnumerator *en=[self objectEnumeratorForSmallerOrEqualMember:vref];
	HistoEntryGen *v;
	while (v=[en prevObject]) {
		if (mindate && [v->date isLessThan:mindate]) break;
		NSEnumerator *ke=[v->_values keyEnumerator];
		NSString *k;
		while (k=[ke nextObject]) {
			if ([res objectForKey:k]) continue;
			[res setObject:[v->_values objectForKey:k] forKey:k];
			c--;
			if (!c) break;
		}
	}
	return res;
}


@end
